using System;
using System.Linq;
using CloudStorage.API;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using CloudStorage.API.Messages;
using CloudStorage.API.Messages.Extensions;

namespace CloudStorage.Tests.API.Messages.Extensions
{
	[TestClass]
	public class IQueueStorageAccountExtensionsTests
	{
		[TestMethod, ExpectedException(typeof(ArgumentNullException))]
		public void QueueExists_expects_queueName()
		{
			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();

			queueStorageAccount.QueueExists(null);
		}

		[TestMethod, ExpectedException(typeof(ArgumentNullException))]
		public void QueueExists_expects__non_empty_queueName()
		{
			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();

			queueStorageAccount.QueueExists(string.Empty);
		}

		[TestMethod]
		public void QueueExists_one_queue_returns_true()
		{
			// Arrange
			var expectedQueueName = "foo";

			var queueListItem = MockRepository.GenerateMock<IQueueListItem>();
			queueListItem.Expect(qli => qli.Name).Return(expectedQueueName);

			var expectedQueues = new[] { queueListItem };

			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();
			var listQueuesResponse = MockRepository.GenerateMock<IListResponse<IQueueListItem>>();

			queueStorageAccount.Expect(qsa => qsa.ListQueues(expectedQueueName))
												 .Return(listQueuesResponse);

			listQueuesResponse.Expect(lqr => lqr.Items)
												.Return(expectedQueues);

			// Act
			var exists = queueStorageAccount.QueueExists(expectedQueueName);

			// Assert
			Assert.IsTrue(exists);
		}

		[TestMethod]
		public void QueueExists_two_queues_returns_false()
		{
			// Arrange
			var expectedQueueName = "foo";

			var queueListItem = MockRepository.GenerateMock<IQueueListItem>();
			queueListItem.Expect(qli => qli.Name)
										.Return(expectedQueueName)
										.Repeat
										.Any();

			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();
			var listQueuesResponse = MockRepository.GenerateMock<IListResponse<IQueueListItem>>();

			queueStorageAccount.Expect(qsa => qsa.ListQueues(expectedQueueName))
												 .Return(listQueuesResponse);

			var expectedQueues = new[] { queueListItem, queueListItem };

			listQueuesResponse.Expect(lqr => lqr.Items)
												.Return(expectedQueues);

			// Act
			var exists = queueStorageAccount.QueueExists(expectedQueueName);

			// Assert
			Assert.IsFalse(exists);
			queueListItem.VerifyAllExpectations();
			queueStorageAccount.VerifyAllExpectations();
			listQueuesResponse.VerifyAllExpectations();
		}

		[TestMethod]
		public void QueueExists_prefix_match_returns_false()
		{
			// Arrange
			var expectedQueueName = "foo";
			var realQueueName = expectedQueueName + "suffix";

			var queueListItem = MockRepository.GenerateMock<IQueueListItem>();
			queueListItem.Expect(qli => qli.Name)
										.Return(realQueueName)
										.Repeat
										.Any();

			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();
			var listQueuesResponse = MockRepository.GenerateMock<IListResponse<IQueueListItem>>();

			queueStorageAccount.Expect(qsa => qsa.ListQueues(expectedQueueName))
												 .Return(listQueuesResponse);

			listQueuesResponse.Expect(lqr => lqr.Items)
												.Return(new[] { queueListItem });

			// Act
			var exists = queueStorageAccount.QueueExists(expectedQueueName);

			// Assert
			Assert.IsFalse(exists);
			queueListItem.VerifyAllExpectations();
			queueStorageAccount.VerifyAllExpectations();
			listQueuesResponse.VerifyAllExpectations();
		}

		[TestMethod]
		public void QueueExists_no_queues_returns_false()
		{
			// Arrange
			var expectedQueueName = "foo";
			var expectedQueues = Enumerable.Empty<IQueueListItem>();

			var queueStorageAccount = MockRepository.GenerateMock<IQueueStorageAccount>();
			var listQueuesResponse = MockRepository.GenerateMock<IListResponse<IQueueListItem>>();

			queueStorageAccount.Expect(qsa => qsa.ListQueues(expectedQueueName))
												 .Return(listQueuesResponse);

			listQueuesResponse.Expect(lqr => lqr.Items)
												.Return(expectedQueues);

			// Act
			var exists = queueStorageAccount.QueueExists(expectedQueueName);

			// Assert
			Assert.IsFalse(exists);
		}
	}
}